package de.szut.ita13sommerfeld.apacheanalyser.statistics;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Map.Entry;
import java.util.Set;

import de.szut.ita13sommerfeld.apacheanalyser.apachelog.ApacheLog;
import de.szut.ita13sommerfeld.apacheanalyser.apachelog.User;
import de.szut.ita13sommerfeld.apacheanalyser.components.ApacheComponent;
import de.szut.ita13sommerfeld.apacheanalyser.libaries.MethodLibary;
import de.szut.ita13sommerfeld.apacheanalyser.libaries.StatusLibary;
import de.szut.ita13sommerfeld.apacheanalyser.libaries.UserLibary;

/**
 * 
 * @author Rene Sommerfeld
 */

public class ApacheStatistics extends BufferedWriter implements ApacheComponent {

	public static final int TO_KB = 1024;
	public static final int TO_MB = TO_KB * 1024;
	
	private ApacheLog log;
	private UserLibary users;
	private MethodLibary methods;
	private StatusLibary status;
	
	private final int DEFECTIVE_LINES;
	private final int TOTAL_LINES;
	private final long DATASIZE_B, DATASIZE_KB, DATASIZE_MB;
	private final long PROCESS_TIME;
	private final Entry<String,Integer> MOSTDOWNLOADED_RESOURCE;
	private String defectivelines;
	private final User MOST_DATAUSAGE_USER;
	
	public ApacheStatistics(ApacheLog log, File statistics) throws IOException {
		super(new FileWriter(statistics.getAbsoluteFile()));
		this.log = log;
		this.users = log.getUserlibary();
		this.methods = log.getMethodlibary();
		this.status = log.getStatuslibary();
		
		TOTAL_LINES = log.getLines();
		defectivelines = "";
		DEFECTIVE_LINES = log.getEntries().getDefectiveLines().size();
		DATASIZE_B = log.getDatasize();
		DATASIZE_KB = DATASIZE_B / TO_KB;
		DATASIZE_MB = DATASIZE_B / TO_MB;
		
		PROCESS_TIME = log.getProcesstime();
		MOSTDOWNLOADED_RESOURCE = log.getResourcelibary().getMostDownloadedResource();
		MOST_DATAUSAGE_USER = log.getUserlibary().getMostDataUsageUser();
	}
	
	public void writeStatistics() throws IOException {
		for(int i = 0; i < DEFECTIVE_LINES; i++) {
			int line = log.getEntries().getDefectiveLines().get(i);
			if(i == 0) defectivelines += "{" + line + ",";
			else if(i == DEFECTIVE_LINES - 1) defectivelines += line + "}";
			else defectivelines += line + ",";
		}
		write(String.format("%s : %s", "Total Lines", TOTAL_LINES));
		newLine();
		write(String.format("%s : %s", "Defective Lines", DEFECTIVE_LINES));
		newLine();
		write(defectivelines);
		newLine();
		write(String.format("%s : %s %s - %s %s - %s %s", "Total Size", DATASIZE_B, "Byte", DATASIZE_KB, "KB", DATASIZE_MB, "MB"));
		newLine();
		write(String.format("%s : %s - %s", "Most Downloaded Resource", MOSTDOWNLOADED_RESOURCE.getKey().toString(), MOSTDOWNLOADED_RESOURCE.getValue() + " Hits"));
		newLine();
		write(String.format("%s : %s - %s - %s", "Most Data Usage User", MOST_DATAUSAGE_USER.getIp(), MOST_DATAUSAGE_USER.getTotalsize() + " Byte", MOST_DATAUSAGE_USER.getEntries().size() + " Entries"));
		newLine();
		write(String.format("%s : %s", "Process Time", PROCESS_TIME + " ms"));
		for(int i = 0; i < 3; i++) newLine();
		write("Request Methods");
		newLine();
		Set<Entry<String, Integer>> methodEntrySet = methods.entrySet();
		for(Entry<String, Integer> method : methodEntrySet) {
			write(String.format("%s : %s", "\t" + method.getKey().toString(), String.valueOf(method.getValue())));
			newLine();
		}
		write("Status Messages");
		newLine();
		Set<Entry<Integer, ArrayList<Integer>>> statusEntrySet = status.entrySet();
		for(Entry<Integer, ArrayList<Integer>> status : statusEntrySet) {
			write(String.format("%s : %s", String.valueOf("\t" + status.getKey().intValue() * 100) + "er", String.valueOf(status.getValue().size())));
			newLine();
		}
		for(int i = 0; i < 2; i++) newLine();
		write("All Users");
		newLine();
		Set<Entry<String, User>> userEntrySet = users.entrySet();
		for(Entry<String, User> user : userEntrySet) {
			String ip = user.getKey().toString();
			long datasize = user.getValue().getTotalsize();
			String first = user.getValue().getFirstAction().getDateString();
			String last = user.getValue().getLastAction().getDateString();
			write(String.format("%s%s", "\tFilesFor_", ip));
			newLine();
			write(String.format("%s : %s", "\t\tTotal Entries", user.getValue().getEntries().size()));
			newLine();
			write(String.format("%s : %s %s - %s %s - %s %s", "\t\tTotal Data Usage", datasize, "Byte", datasize / TO_KB, "KB", datasize / TO_MB, "MB"));
			newLine();
			write(String.format("%s : %s", "\t\tFirst Action", first));
			newLine();
			write(String.format("%s : %s", "\t\tLast Action", last));
			newLine();
			write("\t\tRequested Resources :");
			newLine();
			Set<Entry<String, Integer>> resourceEntrySet = user.getValue().getResources().entrySet();
			for(Entry<String, Integer> resource : resourceEntrySet) {
				String name = resource.getKey().toString();
				int counter = resource.getValue();
				write(String.format("%s : %s", "\t\t\t" + counter, name));
				newLine();
			}
			write("###############################################################################################################");
			newLine();
		}
		close();
	}
}
